#pragma once

#include <iostream>
#include <cstdio>
#include <string>
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include"Comm.hpp"
#define PATH "."
#define FILENAME "fifo"

class NamedFifo
{
    public:
    NamedFifo(const std::string &path,const std::string &name):_path(path),_name(name)
    {
        umask(0);
        _fifoname=_path+"/"+_name;
        int n=mkfifo(_fifoname.c_str(),0666);
        if(n<0) ERR_EXIT("mkfifo");
        else
        {
            std::cout << "mkfifo success" << std::endl;
        }
    }

    ~NamedFifo()
    {
        //删除管道文件
        int n=unlink(_fifoname.c_str());
        if(n==0)  ;//ERR_EXIT("unlink"); 注释掉，因为提前退出导致shm无法正确析构
        else
        {
            std::cout << "remove fifo failed" << std::endl;
        }
    }
    private:
    std::string _path;
    std::string _name;
    std::string _fifoname;
};

class FileOper
{
    public:
    FileOper(const std::string &path,const std::string &name):_path(path),_name(name),_fd(-1)
    {
        _fifoname=_path+"/"+_name;
    }

    void OpenForRead()
    {
        //写端未打开管道文件，读端会阻塞在open调用中
        _fd=open(_fifoname.c_str(),O_RDONLY);
        if (_fd < 0)
        {
            ERR_EXIT("open");
        }
        std::cout << "open fifo success" << std::endl;
    }

    void OpenForWrite()
    {
        //write
        _fd=open(_fifoname.c_str(),O_WRONLY);
         if (_fd < 0)
        {
            ERR_EXIT("open");
        }
        std::cout << "open fifo success" << std::endl;
    }

    void Wakeup()//write改写为唤醒
    {
        //写入操作
        char c='c';
        int n=write(_fd,&c,1);
        printf("尝试唤醒: %d\n", n);
    }

    bool Wait()//Read改写为Wait
    {
        char c;
        int number=read(_fd,&c,1);
        if(number>0)
        {
            printf("醒来: %d\n", number);
            return true;
        }
        return false;
    }
        void Close()
        {
            if(_fd>0)
            close(_fd);
        }
        ~FileOper()
        {}
    private:
    std::string _path;
    std::string _name;
    std::string _fifoname;
    int _fd;
};